package com.spring.shops.service.impl;

import com.spring.shops.constant.MessageConstant;
import com.spring.shops.context.BaseContext;
import com.spring.shops.dao.TzSysMenuMapper;
import com.spring.shops.dao.TzSysRoleMenuMapper;
import com.spring.shops.dao.TzSysUserRoleMapper;
import com.spring.shops.model.dto.SysMenuDTO;
import com.spring.shops.model.dto.SysUserDTO;
import com.spring.shops.model.entity.TzSysMenu;
import com.spring.shops.model.result.MenuAndPermsData;
import com.spring.shops.model.result.ServerResponseEntityVoid;
import com.spring.shops.model.vo.SysMenuVO;
import com.spring.shops.model.vo.SysMenuVO2;
import com.spring.shops.service.MenuService;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl implements MenuService {
    @Autowired
    private TzSysMenuMapper menuMapper;
    @Autowired
    private TzSysUserRoleMapper userRoleMapper;
    @Autowired
    private TzSysRoleMenuMapper roleMenuMapper;
    /**
     * 获取所有的权限列表
     * @return
     */
    @Override
    public ServerResponseEntityVoid<List<SysMenuVO>> table() {
        List<TzSysMenu> menuList=menuMapper.selectAll();
        List<SysMenuVO> menuListVO=new ArrayList<>();
        //属性拷贝
        for (TzSysMenu tzSysMenu : menuList) {
            SysMenuVO menuVO = getMenuVO(tzSysMenu);
            menuListVO.add(menuVO);
        }
        return ServerResponseEntityVoid.success(menuListVO);
    }

    /**
     * 通过登陆用户的userId获取用户所拥有的菜单和权限(不包括按钮）
     * @return
     */
    @Override
    public ServerResponseEntityVoid<List<SysMenuVO>> list() {
       //获取当前用户的id
        Long currentId = BaseContext.getCurrentId();
        //根据当前用户的id获取当前用户的角色
        List<Long> roleIdList = userRoleMapper.selectByUserId(currentId);
        List<SysMenuVO> menuVOList=new ArrayList<>();
        //遍历每个角色id查询改角色有哪些权限
        for (Long roleId : roleIdList) {
            List<Integer> menuIdList = roleMenuMapper.selectByRoleId(roleId);
            //获取每一个权限需要的信息
            for (Integer menuId : menuIdList) {
                Long menuId2= Long.valueOf(menuId);
                TzSysMenu tzSysMenu = menuMapper.selectByParentId(menuId2);
                //需要判断权限是否是按钮，是的话直接跳过
                if(Objects.equals(tzSysMenu.getType(), MessageConstant.MENU_TYPE_BUTTON)){
                    continue;
                }
                SysMenuVO menuVO = getMenuVO(tzSysMenu);
                if(menuVO!=null){
                    menuVOList.add(menuVO);
                }

            }
        }

        return ServerResponseEntityVoid.success(menuVOList);
    }
    /**
     * 获取用户所拥有的菜单和权限
     */
    @Override
    public ServerResponseEntityVoid<MenuAndPermsData> getMenuAndPerms() {
        //获取当前用户的id
        Long currentId = BaseContext.getCurrentId();
        //多表联查
        List<TzSysMenu> menuList = menuMapper.selectByUserId(currentId);
        //然后对搜集的结果按照parentId进行分组(key:parentId value:该parentId下的所有子菜单）
        Map<Long, List<TzSysMenu>> sysMenuLevelMap = menuList.stream()
                .sorted(Comparator.comparing(TzSysMenu::getOrderNum))
                .collect(Collectors.groupingBy(TzSysMenu::getParentId));
        // 一级菜单
        List<TzSysMenu> rootMenu = sysMenuLevelMap.get(0L);
        List<SysMenuVO2> sysMenuVOList = new ArrayList<>();
        if (rootMenu != null) {
            // 二级菜单
            for (TzSysMenu sysMenu : rootMenu) {
                SysMenuVO2 menuVO = getMenuVO2(sysMenu);
                List<TzSysMenu> menuList1 = sysMenuLevelMap.get(sysMenu.getMenuId());
                List<SysMenuVO2> menuVOList = new ArrayList<>();
                for (TzSysMenu tzSysMenu : menuList1) {
                    menuVOList.add(getMenuVO2(tzSysMenu));
                }
                menuVO.setList(menuVOList);
                sysMenuVOList.add(menuVO);
            }
        }
        MenuAndPermsData menuAndPermsData = new MenuAndPermsData();
        menuAndPermsData.setMenuList(sysMenuVOList);
        //获取当前用户的权限
        List<String> perms=menuMapper.getPermsByUserId(currentId);
        List<String> resPerms=new ArrayList<>();
        //需要对查询的权限进行处理
        for (String perm : perms) {
            String[] split = perm.split(",");
            for (String subPerm : split) {
                resPerms.add(subPerm);
            }

        }
        menuAndPermsData.setAuthorities(resPerms);
        return ServerResponseEntityVoid.success(menuAndPermsData);
    }
    /**
     * 新增菜单数据
     * @param dto
     * @return
     */
    @Override
    public ServerResponseEntityVoid save(SysMenuDTO dto) {
        TzSysMenu menu = getMenu(dto);
        int rows = menuMapper.insert(menu);
        if(rows>0){
            return ServerResponseEntityVoid.success();
        }else return ServerResponseEntityVoid.error();
    }
    /**
     * 根据菜单id获取信息
     * @param menuId
     * @return
     */
    @Override
    public ServerResponseEntityVoid<SysMenuVO> getInfoById(Long menuId) {
        TzSysMenu tzSysMenu = menuMapper.selectByPrimaryKey(menuId);
        SysMenuVO menuVO = getMenuVO(tzSysMenu);
        return ServerResponseEntityVoid.success(menuVO);
    }
    /**
     * 更新菜单信息
     * @param dto
     * @return
     */
    @Override
    public ServerResponseEntityVoid update(SysMenuDTO dto) {
        TzSysMenu menu = getMenu(dto);
        menu.setMenuId(dto.getMenuId());
        //进行数据更新
        int rows = menuMapper.updateByPrimaryKey(menu);
        if(rows>0){
            return ServerResponseEntityVoid.success();
        }else return ServerResponseEntityVoid.error();
    }
    /**
     * 根据id删除数据
     * @param menuId
     * @return
     */
    @Override
    public ServerResponseEntityVoid deleteById(Long menuId) {
        int rows = menuMapper.deleteByPrimaryKey(menuId);
        if(rows>0){
            return ServerResponseEntityVoid.success();
        }else return ServerResponseEntityVoid.error();
    }

    //dto->entity
    public TzSysMenu getMenu(SysMenuDTO dto){
        return new TzSysMenu(
                dto.getParentId(),dto.getName(),dto.getUrl(),
                dto.getPerms(),dto.getType(),dto.getIcon(),dto.getOrderNum()
        );
    }
    //entity->vo
    public SysMenuVO getMenuVO(TzSysMenu menu){
        if(menu!=null){//一定要判断，数据库坑人
            return new SysMenuVO(
                    menu.getMenuId(),menu.getParentId(),null,menu.getName(),menu.getUrl(),
                    menu.getPerms(),menu.getType(),null,menu.getOrderNum(),null
            );
        }
        return null;

    }
    public SysMenuVO2 getMenuVO2(TzSysMenu menu){
        if(menu!=null){//一定要判断，数据库坑人
            return new SysMenuVO2(
                    menu.getMenuId(),menu.getParentId(),null,menu.getName(),menu.getUrl(),
                    menu.getPerms(),menu.getType(),null,menu.getOrderNum(),null
            );
        }
        return null;

    }
}
